package mop.gui.task;

import java.awt.GridLayout;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SpringLayout;
import mop.controller.ModifyTaskDetailsController;
import mop.controller.UpdateTaskStatusController;
import mop.gui.GUI;
import mop.gui.component.SpringUtilities;
import mop.model.task.TaskInterface;
import mop.model.task.field.FieldInterface;

/**
 * TaskDetailsDialog
 * 
 * @author  MOP Team 7
 */
public class TaskDetailsDialog extends javax.swing.JDialog 
{
    /**
     * Constructor.
     * 
     * @param   gui
     * @param   modifyTaskDetailsController
     * @param   updateTaskStatusController
     * @param   task
     */
    public TaskDetailsDialog(GUI gui, ModifyTaskDetailsController modifyTaskDetailsController, 
            UpdateTaskStatusController updateTaskStatusController, TaskInterface task)
    {
        super(gui.getMainWindow(), true);
        initComponents();
        
        setGui(gui);
        this.modifyTaskDetailsController = modifyTaskDetailsController;
        this.updateTaskStatusController = updateTaskStatusController;
        
        // Set selected task.
        this.task = task;
        this.txtId.setText(task.getId());
        this.txtTaskType.setText(task.getTaskType().getDescription());
        this.txtStatus.setText(task.getStatus().getName());
        
        // Load start & deadline in correct format.
        this.txtStartTime.setText(this.dateTimeFormat.format(new Date(task.getSchedule().getStart().getTime())));
        this.txtDeadline.setText(this.dateTimeFormat.format(new Date(task.getSchedule().getDeadline().getTime())));
        
        // Load duration (calculate weeks, days, hours, minutes).
        long ms = task.getSchedule().getDuration().getTime();
        long weeks = (long) Math.floor(ms / 604800000); // #weken
        this.txtDurationWeeks.setText(Long.toString(weeks));
        ms = ms % 604800000; // rest
        long days = (long) Math.floor(ms / 86400000); // #dagen
        this.txtDurationDays.setText(Long.toString(days));
        ms = ms % 86400000; // rest
        long hours = (long) Math.floor(ms / 3600000); // #uren
        this.txtDurationHours.setText(Long.toString(hours));
        ms = ms % 3600000; // rest
        long minutes = (long) Math.floor(ms / 60000); // #minuten
        this.txtDurationMinutes.setText(Long.toString(minutes));
        ms = ms % 60000; // rest

        // Load project
        if (task.getProject() != null)
            this.txtProject.setText(task.getProject().getDescription());

        // Fill custom panel
        this.fields = task.getFieldList();
        //this.pnlCustom.setLayout(new GridLayout(task.getFieldList().size(), 2));
        this.pnlCustom.setLayout(new SpringLayout());
        this.inputs = new LinkedList<JTextField>();
        for (FieldInterface f : this.fields)
        {
            JLabel label = new JLabel(f.getDescription());
            this.pnlCustom.add(label);
            JTextField textfield = new JTextField(f.getValue(), 10);
            textfield.setHorizontalAlignment(JTextField.LEFT);
            this.inputs.add(textfield);
            this.pnlCustom.add(textfield);
        }
        SpringUtilities.makeCompactGrid(this.pnlCustom,
            task.getFieldList().size(), 2, //rows, cols
            5, 5, //initialX, initialY
            5, 5);//xPad, yPad
      
        // Load dep tasks
        loadTasks();
    }
    
    /***************************************************************************
     *                          GUI reference
     ***************************************************************************/
    
    private GUI gui;
    
    /**
     * Sets the GUI.
     * 
     * @param   gui
     * @post    gui is set.
     */
    private void setGui(GUI gui)
    {
        this.gui = gui;
    }
    
    /**
     * Returns the GUI reference.
     * 
     * @return  this.gui
     */
    public GUI getGui()
    {
        return this.gui;
    }
    
    /***************************************************************************
     *                          Controllers
     ***************************************************************************/
    
    private ModifyTaskDetailsController modifyTaskDetailsController;
    private UpdateTaskStatusController updateTaskStatusController;
    
    /***************************************************************************
     *                          Selected task
     ***************************************************************************/
    
    private TaskInterface task;

    /***************************************************************************
     *                          Fields
     ***************************************************************************/

    private List<FieldInterface> fields;
    private List<JTextField> inputs;
    
    /***************************************************************************
     *                          Dialog-specific functionality
     ***************************************************************************/

    // keep track of checkboxes
    private LinkedList<JCheckBox> taskBoxes;

    /**
     * Loads the list of tasks on which the new task can depend.
     */
    private void loadTasks()
    {
        LinkedList<TaskInterface> tasks = (LinkedList<TaskInterface>) modifyTaskDetailsController.getAllTasks();
        LinkedList<TaskInterface> depTasks = (LinkedList<TaskInterface>) task.getDependencyList();

        // load panel with checkboxes
        this.taskBoxes = new LinkedList<JCheckBox>();
        pnlTasks.setLayout(new GridLayout(tasks.size(), 1));
        for ( TaskInterface t : tasks )
        {
            JCheckBox newBox = new JCheckBox(t.getId());
            this.taskBoxes.add(newBox);
            pnlTasks.add(newBox);
            if (depTasks.contains(t))
                newBox.setSelected(true);
        }
    }

    private DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT);

    /**
     * Validate and set the datetime field on the screen given a datetime string.
     * @param dateTime The datetime string
     */
    public void setStart(String dateTimeString)
    {
        this.setStart(this.getDateTime(dateTimeString));
    }

    /**
     * Validate and set the datetime field on the screen given a date.
     * @param dateTime The datetime object
     */
    public void setStart(Date dateTime)
    {
        String dateTimeString = "";
        if (dateTime != null)
            dateTimeString = dateTimeFormat.format(dateTime);
        txtStartTime.setText(dateTimeString);
        btnStartDate.setTargetDate(dateTime);
        btnStartTime.setTargetDate(dateTime);
    }

    /**
     * Returns the start time as a Date object.
     *
     * @return  start time as Date
     */
    public Date getStart()
    {
        return this.getDateTime(txtStartTime.getText());
    }

    /**
     * Validate and set the datetime field on the screen given a datetime string.
     * @param dateTime The datetime string
     */
    public void setDeadline(String dateTimeString)
    {
        this.setDeadline(this.getDateTime(dateTimeString));
    }

    /**
     * Validate and set the datetime field on the screen given a date.
     * @param dateTime The datetime object
     */
    public void setDeadline(Date dateTime)
    {
        String dateTimeString = "";
        if (dateTime != null)
            dateTimeString = dateTimeFormat.format(dateTime);
        txtDeadline.setText(dateTimeString);
        btnDeadlineDate.setTargetDate(dateTime);
        btnDeadlineTime.setTargetDate(dateTime);
    }

    /**
     * Returns the deadline as a Date object.
     *
     * @return  deadline as Date
     */
    public Date getDeadline()
    {
        return this.getDateTime(txtDeadline.getText());
    }

    /**
     * Returns a given date time string as a Date object.
     *
     * @return  Date object
     */
    public Date getDateTime(String dateTimeString)
    {
        Date dateTime = null;
        try
        {
            if ((dateTimeString != null) && (dateTimeString.length() > 0))
                dateTime = dateTimeFormat.parse(dateTimeString);
	}
        catch (Exception e)
        {
            dateTime = null;
        }
        return dateTime;
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lblTaskDetails = new javax.swing.JLabel();
        btnModify = new javax.swing.JButton();
        btnCancel = new javax.swing.JButton();
        paneDetails = new javax.swing.JTabbedPane();
        pnlDetails = new javax.swing.JPanel();
        lblId = new javax.swing.JLabel();
        txtId = new javax.swing.JTextField();
        lblType = new javax.swing.JLabel();
        txtTaskType = new javax.swing.JTextField();
        lblStatus = new javax.swing.JLabel();
        txtStatus = new javax.swing.JTextField();
        btnChangeStatus = new javax.swing.JButton();
        lblProject = new javax.swing.JLabel();
        txtProject = new javax.swing.JTextField();
        pnlTiming = new javax.swing.JPanel();
        lblStartTime = new javax.swing.JLabel();
        txtStartTime = new javax.swing.JTextField();
        lblDeadline = new javax.swing.JLabel();
        txtDeadline = new javax.swing.JTextField();
        btnDeadlineDate = new org.sourceforge.jcalendarbutton.JCalendarButton();
        btnStartDate = new org.sourceforge.jcalendarbutton.JCalendarButton();
        btnDeadlineTime = new net.sourceforge.jcalendarbutton.JTimeButton();
        lblDurationWeeks = new javax.swing.JLabel();
        txtDurationWeeks = new javax.swing.JTextField();
        txtDurationHours = new javax.swing.JTextField();
        lblDurationHours = new javax.swing.JLabel();
        txtDurationMinutes = new javax.swing.JTextField();
        lblDurationMinutes = new javax.swing.JLabel();
        lblDurationDays = new javax.swing.JLabel();
        txtDurationDays = new javax.swing.JTextField();
        btnStartTime = new net.sourceforge.jcalendarbutton.JTimeButton();
        pnlFields = new javax.swing.JPanel();
        scrlFields = new javax.swing.JScrollPane();
        pnlCustom = new javax.swing.JPanel();
        pnlDepTasks = new javax.swing.JPanel();
        lblDepTasks = new javax.swing.JLabel();
        scrlTasks = new javax.swing.JScrollPane();
        pnlTasks = new javax.swing.JPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Task Details");

        lblTaskDetails.setFont(new java.awt.Font("Tahoma", 1, 12));
        lblTaskDetails.setText("Task Details");
        lblTaskDetails.setName("lblTaskDetails"); // NOI18N

        btnModify.setText("Modify");
        btnModify.setName("btnModify"); // NOI18N
        btnModify.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnModifyActionPerformed(evt);
            }
        });

        btnCancel.setText("Cancel");
        btnCancel.setName("btnCancel"); // NOI18N
        btnCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCancelActionPerformed(evt);
            }
        });

        paneDetails.setName("paneDetails"); // NOI18N

        pnlDetails.setName("pnlDetails"); // NOI18N

        lblId.setText("Task Id");
        lblId.setName("lblId"); // NOI18N

        txtId.setEditable(false);
        txtId.setName("txtId"); // NOI18N

        lblType.setText("Task Type");
        lblType.setName("lblType"); // NOI18N

        txtTaskType.setEditable(false);
        txtTaskType.setName("txtTaskType"); // NOI18N

        lblStatus.setText("Status");
        lblStatus.setName("lblStatus"); // NOI18N

        txtStatus.setEditable(false);
        txtStatus.setName("txtStatus"); // NOI18N

        btnChangeStatus.setText("Change Status");
        btnChangeStatus.setName("btnChangeStatus"); // NOI18N
        btnChangeStatus.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnChangeStatusActionPerformed(evt);
            }
        });

        lblProject.setText("Project");
        lblProject.setName("lblProject"); // NOI18N

        txtProject.setEditable(false);
        txtProject.setName("txtProject"); // NOI18N

        javax.swing.GroupLayout pnlDetailsLayout = new javax.swing.GroupLayout(pnlDetails);
        pnlDetails.setLayout(pnlDetailsLayout);
        pnlDetailsLayout.setHorizontalGroup(
            pnlDetailsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlDetailsLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlDetailsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(lblType)
                    .addComponent(lblId)
                    .addComponent(lblStatus)
                    .addComponent(lblProject))
                .addGap(18, 18, 18)
                .addGroup(pnlDetailsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(txtTaskType, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE)
                    .addComponent(txtId, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlDetailsLayout.createSequentialGroup()
                        .addComponent(txtStatus, javax.swing.GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnChangeStatus))
                    .addComponent(txtProject, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE))
                .addContainerGap())
        );
        pnlDetailsLayout.setVerticalGroup(
            pnlDetailsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlDetailsLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlDetailsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblId)
                    .addComponent(txtId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlDetailsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblType)
                    .addComponent(txtTaskType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlDetailsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblStatus)
                    .addComponent(txtStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btnChangeStatus))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlDetailsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblProject)
                    .addComponent(txtProject, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(189, Short.MAX_VALUE))
        );

        paneDetails.addTab("Details", pnlDetails);

        pnlTiming.setName("Timing"); // NOI18N

        lblStartTime.setText("Start Time");
        lblStartTime.setName("lblStartTime"); // NOI18N

        txtStartTime.setName("txtStartTime"); // NOI18N
        txtStartTime.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                focusStart(evt);
            }
        });

        lblDeadline.setText("Deadline");
        lblDeadline.setName("lblDeadline"); // NOI18N

        txtDeadline.setName("txtDeadline"); // NOI18N
        txtDeadline.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                focusDeadline(evt);
            }
        });

        btnDeadlineDate.setName("btnDeadlineDate"); // NOI18N
        btnDeadlineDate.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                changeDeadline(evt);
            }
        });

        btnStartDate.setName("btnStartDate"); // NOI18N
        btnStartDate.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                changeStart(evt);
            }
        });

        btnDeadlineTime.setName("btnDeadlineTime"); // NOI18N
        btnDeadlineTime.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                changeDeadline(evt);
            }
        });

        lblDurationWeeks.setText("Duration - Weeks");
        lblDurationWeeks.setName("lblDurationWeeks"); // NOI18N

        txtDurationWeeks.setText("0");
        txtDurationWeeks.setName("txtDurationWeeks"); // NOI18N

        txtDurationHours.setText("0");
        txtDurationHours.setName("txtDurationHours"); // NOI18N

        lblDurationHours.setText("Duration - Hours");
        lblDurationHours.setName("lblDurationHours"); // NOI18N

        txtDurationMinutes.setText("0");
        txtDurationMinutes.setName("txtDurationMinutes"); // NOI18N

        lblDurationMinutes.setText("Duration - Minutes");
        lblDurationMinutes.setName("lblDurationMinutes"); // NOI18N

        lblDurationDays.setText("Duration - Days");
        lblDurationDays.setName("lblDurationDays"); // NOI18N

        txtDurationDays.setText("0");
        txtDurationDays.setName("txtDurationDays"); // NOI18N

        btnStartTime.setName("btnStartTime"); // NOI18N
        btnStartTime.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                changeStart(evt);
            }
        });

        javax.swing.GroupLayout pnlTimingLayout = new javax.swing.GroupLayout(pnlTiming);
        pnlTiming.setLayout(pnlTimingLayout);
        pnlTimingLayout.setHorizontalGroup(
            pnlTimingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlTimingLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlTimingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(txtDurationWeeks, javax.swing.GroupLayout.DEFAULT_SIZE, 277, Short.MAX_VALUE)
                    .addComponent(lblStartTime)
                    .addComponent(lblDeadline)
                    .addGroup(pnlTimingLayout.createSequentialGroup()
                        .addComponent(btnStartDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnStartTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txtStartTime, javax.swing.GroupLayout.DEFAULT_SIZE, 223, Short.MAX_VALUE))
                    .addComponent(lblDurationDays)
                    .addComponent(lblDurationHours)
                    .addComponent(lblDurationMinutes)
                    .addGroup(pnlTimingLayout.createSequentialGroup()
                        .addComponent(btnDeadlineDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnDeadlineTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txtDeadline, javax.swing.GroupLayout.DEFAULT_SIZE, 223, Short.MAX_VALUE))
                    .addComponent(lblDurationWeeks)
                    .addComponent(txtDurationDays, javax.swing.GroupLayout.DEFAULT_SIZE, 277, Short.MAX_VALUE)
                    .addComponent(txtDurationHours, javax.swing.GroupLayout.DEFAULT_SIZE, 277, Short.MAX_VALUE)
                    .addComponent(txtDurationMinutes, javax.swing.GroupLayout.DEFAULT_SIZE, 277, Short.MAX_VALUE))
                .addContainerGap())
        );
        pnlTimingLayout.setVerticalGroup(
            pnlTimingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlTimingLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblStartTime)
                .addGap(7, 7, 7)
                .addGroup(pnlTimingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(pnlTimingLayout.createSequentialGroup()
                        .addGroup(pnlTimingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(btnStartDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(btnStartTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(lblDeadline))
                    .addComponent(txtStartTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlTimingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(btnDeadlineDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btnDeadlineTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txtDeadline, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(lblDurationWeeks)
                .addGap(9, 9, 9)
                .addComponent(txtDurationWeeks, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(lblDurationDays)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(txtDurationDays, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(lblDurationHours)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(txtDurationHours, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(lblDurationMinutes)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(txtDurationMinutes, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        paneDetails.addTab("Timing", pnlTiming);

        pnlFields.setName("pnlFields"); // NOI18N

        scrlFields.setName("scrlFields"); // NOI18N

        pnlCustom.setName("pnlCustom"); // NOI18N

        javax.swing.GroupLayout pnlCustomLayout = new javax.swing.GroupLayout(pnlCustom);
        pnlCustom.setLayout(pnlCustomLayout);
        pnlCustomLayout.setHorizontalGroup(
            pnlCustomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 277, Short.MAX_VALUE)
        );
        pnlCustomLayout.setVerticalGroup(
            pnlCustomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 276, Short.MAX_VALUE)
        );

        scrlFields.setViewportView(pnlCustom);

        pnlFields.add(scrlFields);

        paneDetails.addTab("Fields", pnlFields);

        pnlDepTasks.setName("pnlDepTasks"); // NOI18N

        lblDepTasks.setText("Depends on tasks...");
        lblDepTasks.setName("lblDepTasks"); // NOI18N

        scrlTasks.setName("scrlTasks"); // NOI18N

        pnlTasks.setName("pnlTasks"); // NOI18N

        javax.swing.GroupLayout pnlTasksLayout = new javax.swing.GroupLayout(pnlTasks);
        pnlTasks.setLayout(pnlTasksLayout);
        pnlTasksLayout.setHorizontalGroup(
            pnlTasksLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 277, Short.MAX_VALUE)
        );
        pnlTasksLayout.setVerticalGroup(
            pnlTasksLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 240, Short.MAX_VALUE)
        );

        scrlTasks.setViewportView(pnlTasks);

        javax.swing.GroupLayout pnlDepTasksLayout = new javax.swing.GroupLayout(pnlDepTasks);
        pnlDepTasks.setLayout(pnlDepTasksLayout);
        pnlDepTasksLayout.setHorizontalGroup(
            pnlDepTasksLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlDepTasksLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlDepTasksLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(scrlTasks, javax.swing.GroupLayout.DEFAULT_SIZE, 277, Short.MAX_VALUE)
                    .addComponent(lblDepTasks))
                .addContainerGap())
        );
        pnlDepTasksLayout.setVerticalGroup(
            pnlDepTasksLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlDepTasksLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblDepTasks)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(scrlTasks, javax.swing.GroupLayout.DEFAULT_SIZE, 265, Short.MAX_VALUE)
                .addContainerGap())
        );

        paneDetails.addTab("Dependencies", pnlDepTasks);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(paneDetails, javax.swing.GroupLayout.DEFAULT_SIZE, 302, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(lblTaskDetails)
                            .addComponent(btnModify, javax.swing.GroupLayout.DEFAULT_SIZE, 194, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblTaskDetails)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(paneDetails, javax.swing.GroupLayout.DEFAULT_SIZE, 326, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnModify)
                    .addComponent(btnCancel))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

/**
 * Closes the dialog.
 * 
 * @param   evt
 */
private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed
    this.dispose();
}//GEN-LAST:event_btnCancelActionPerformed

private void focusStart(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_focusStart
    setStart(txtStartTime.getText());
}//GEN-LAST:event_focusStart

private void changeStart(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_changeStart
    if (evt.getNewValue() instanceof Date)
        setStart((Date)evt.getNewValue());
}//GEN-LAST:event_changeStart

private void focusDeadline(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_focusDeadline
    setDeadline(txtDeadline.getText());
}//GEN-LAST:event_focusDeadline

private void changeDeadline(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_changeDeadline
    if (evt.getNewValue() instanceof Date)
        setDeadline((Date)evt.getNewValue());
}//GEN-LAST:event_changeDeadline

private void btnChangeStatusActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnChangeStatusActionPerformed
    (new TaskStatusDialog(gui, updateTaskStatusController, task)).setVisible(true);
    this.txtStatus.setText(task.getStatus().getName());
}//GEN-LAST:event_btnChangeStatusActionPerformed

    /**
     * Creates a task.
     *
     * @param   evt
     */
    private void btnModifyActionPerformed(java.awt.event.ActionEvent evt)
    {
        // Parse start and end time/dates.
        Timestamp start = null;
        Timestamp deadline = null;
        try {
            start = new Timestamp(this.getStart().getTime());
            deadline = new Timestamp(this.getDeadline().getTime());
        } catch (Throwable th) {
            gui.handleError("There's something wrong with the start and/or deadline date & time!");
            return;
        }

        // Load duration.
        long ms = 0;
        ms += Long.parseLong(this.txtDurationMinutes.getText()) * 60000; // 1 minute = 60k ms
        ms += Long.parseLong(this.txtDurationHours.getText()) * 3600000; // 1 hour = 3.6m ms
        ms += Long.parseLong(this.txtDurationDays.getText()) * 86400000; // 1 day = 86.4m ms
        ms += Long.parseLong(this.txtDurationWeeks.getText()) * 604800000; // 1 week = 604.8m ms
        Timestamp duration = new Timestamp(ms);

        // Check custom field inputs
        HashMap<String,String> fieldInputs = new HashMap<String,String>();
        int i = 0;
        for (JTextField tf : this.inputs)
        {
            FieldInterface field = fields.get(i++);
            String input = tf.getText();

            // @TODO Ook checken of Field van IntField or StringField is.
            if (input == null || input.equals(""))
            {
                gui.handleError("You left some fields blank!");
                return;
            }

            fieldInputs.put(field.getId(), input);
        }

        // Load dependant tasks.
        LinkedList<String> depTasks = new LinkedList<String>();
        for ( JCheckBox box : this.taskBoxes )
            if ( box.isSelected() )
                depTasks.add(box.getText());

        // Call controller.
        try {
            modifyTaskDetailsController.updateTaskDetails(this.task.getId(), fieldInputs, start, duration, deadline, depTasks);
            gui.handleSuccess("Task details modified!");
            gui.getMainWindow().update();
            this.dispose();
        } catch (Throwable exception) {
            gui.handleError(exception);
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnCancel;
    private javax.swing.JButton btnChangeStatus;
    private org.sourceforge.jcalendarbutton.JCalendarButton btnDeadlineDate;
    private net.sourceforge.jcalendarbutton.JTimeButton btnDeadlineTime;
    private javax.swing.JButton btnModify;
    private org.sourceforge.jcalendarbutton.JCalendarButton btnStartDate;
    private net.sourceforge.jcalendarbutton.JTimeButton btnStartTime;
    private javax.swing.JLabel lblDeadline;
    private javax.swing.JLabel lblDepTasks;
    private javax.swing.JLabel lblDurationDays;
    private javax.swing.JLabel lblDurationHours;
    private javax.swing.JLabel lblDurationMinutes;
    private javax.swing.JLabel lblDurationWeeks;
    private javax.swing.JLabel lblId;
    private javax.swing.JLabel lblProject;
    private javax.swing.JLabel lblStartTime;
    private javax.swing.JLabel lblStatus;
    private javax.swing.JLabel lblTaskDetails;
    private javax.swing.JLabel lblType;
    private javax.swing.JTabbedPane paneDetails;
    private javax.swing.JPanel pnlCustom;
    private javax.swing.JPanel pnlDepTasks;
    private javax.swing.JPanel pnlDetails;
    private javax.swing.JPanel pnlFields;
    private javax.swing.JPanel pnlTasks;
    private javax.swing.JPanel pnlTiming;
    private javax.swing.JScrollPane scrlFields;
    private javax.swing.JScrollPane scrlTasks;
    private javax.swing.JTextField txtDeadline;
    private javax.swing.JTextField txtDurationDays;
    private javax.swing.JTextField txtDurationHours;
    private javax.swing.JTextField txtDurationMinutes;
    private javax.swing.JTextField txtDurationWeeks;
    private javax.swing.JTextField txtId;
    private javax.swing.JTextField txtProject;
    private javax.swing.JTextField txtStartTime;
    private javax.swing.JTextField txtStatus;
    private javax.swing.JTextField txtTaskType;
    // End of variables declaration//GEN-END:variables
}